package com.mazaiting.util;

import java.util.ArrayList;

/**
 * 访问标识符工具类
 *
 * @author mazaiting
 * @since 2021/8/13
 */
public class AccessFlagUtil {
    public static final short ACC_PUBLIC       = 0x0001;
    public static final short ACC_PRIVATE      = 0x0002;
    public static final short ACC_PROTECTED    = 0x0004;
    public static final short ACC_STATIC       = 0x0008;
    public static final short ACC_FINAL        = 0x0010;
    public static final short ACC_SYNCHRONIZED = 0x0020;
    public static final short ACC_VOLATILE     = 0x0040;
    public static final short ACC_BRIDGE       = 0x0040;
    public static final short ACC_TRANSIENT    = 0x0080;
    public static final short ACC_VARARGS      = 0x0080;
    public static final short ACC_NATIVE       = 0x0100;
    public static final short ACC_INTERFACE    = 0x0200;
    public static final short ACC_ABSTRACT     = 0x0400;
    public static final short ACC_STRICT       = 0x0800;
    public static final short ACC_SYNTHETIC    = 0x1000;
    public static final short ACC_ANNOTATION   = 0x2000;
    public static final short ACC_ENUM         = 0x4000;
    /**
     * 仅在编译时存在
     */
    public static final short ACC_SUPER        = 0x0020;
    /**
     * 判断是否有这个标识
     * @param flags 待判断的标识
     * @param access 访问标识
     * @return true: 包含; false: 不包含
     */
    public static boolean hasFlag(int flags, short access) {
        return (flags & access) != 0;
    }

    /**
     * 根据数值获取类访问标识符
     * @return 标识符数组
     */
    public static String getClassFlags(int flags) {
        ArrayList<String> strings = new ArrayList<>();
        if (hasFlag(flags, ACC_PUBLIC)) strings.add("ACC_PUBLIC");
        if (hasFlag(flags, ACC_FINAL)) strings.add("ACC_FINAL");
        if (hasFlag(flags, ACC_SUPER)) strings.add("ACC_SUPER");
        if (hasFlag(flags, ACC_INTERFACE)) strings.add("ACC_INTERFACE");
        if (hasFlag(flags, ACC_ABSTRACT)) strings.add("ACC_ABSTRACT");
        if (hasFlag(flags, ACC_SYNTHETIC)) strings.add("ACC_SYNTHETIC");
        if (hasFlag(flags, ACC_ANNOTATION)) strings.add("ACC_ANNOTATION");
        if (hasFlag(flags, ACC_ENUM)) strings.add("ACC_ENUM");
        return strings.toString();
    }

    /**
     * 根据数值获取字段访问标识符
     * @return 标识符数组
     */
    public static String getFieldFlags(int flags) {
        ArrayList<String> strings = new ArrayList<>();
        if (hasFlag(flags, ACC_PUBLIC)) strings.add("ACC_PUBLIC");
        if (hasFlag(flags, ACC_PRIVATE)) strings.add("ACC_PRIVATE");
        if (hasFlag(flags, ACC_PROTECTED)) strings.add("ACC_PROTECTED");
        if (hasFlag(flags, ACC_STATIC)) strings.add("ACC_STATIC");
        if (hasFlag(flags, ACC_FINAL)) strings.add("ACC_FINAL");
        if (hasFlag(flags, ACC_VOLATILE)) strings.add("ACC_VOLATILE");
        if (hasFlag(flags, ACC_TRANSIENT)) strings.add("ACC_TRANSIENT");
        if (hasFlag(flags, ACC_SYNTHETIC)) strings.add("ACC_SYNTHETIC");
        if (hasFlag(flags, ACC_ENUM)) strings.add("ACC_ENUM");
        return strings.toString();
    }

    /**
     * 根据数值获取方法访问标识符
     * @return 标识符数组
     */
    public static String getMethodFlags(int flags) {
        ArrayList<String> strings = new ArrayList<>();
        if (hasFlag(flags, ACC_PUBLIC)) strings.add("ACC_PUBLIC");
        if (hasFlag(flags, ACC_PRIVATE)) strings.add("ACC_PRIVATE");
        if (hasFlag(flags, ACC_PROTECTED)) strings.add("ACC_PROTECTED");
        if (hasFlag(flags, ACC_STATIC)) strings.add("ACC_STATIC");
        if (hasFlag(flags, ACC_FINAL)) strings.add("ACC_FINAL");
        if (hasFlag(flags, ACC_SYNCHRONIZED)) strings.add("ACC_SYNCHRONIZED");
        if (hasFlag(flags, ACC_BRIDGE)) strings.add("ACC_BRIDGE");
        if (hasFlag(flags, ACC_VARARGS)) strings.add("ACC_VARARGS");
        if (hasFlag(flags, ACC_NATIVE)) strings.add("ACC_NATIVE");
        if (hasFlag(flags, ACC_ABSTRACT)) strings.add("ACC_ABSTRACT");
        if (hasFlag(flags, ACC_STRICT)) strings.add("ACC_STRICT");
        if (hasFlag(flags, ACC_SYNTHETIC)) strings.add("ACC_SYNTHETIC");
        return strings.toString();
    }
}


















